using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using AutumnEngine.Modules;

namespace AutumnEngine
{
    /// <summary>
    /// The basic class in AutumnEngine. Controls modules. graphics and content.
    /// </summary>
     public static partial class Engine
     {
         /// <summary>
         /// Gets the id of the last added scene.
         /// </summary>
         /// <value>The last id.</value>
         public static UInt32 LastId
         {
             get;
             internal set;
         }
         /// <summary>
         /// Gets the game time.
         /// </summary>
         /// <value>The game time.</value>
         public static GameTime GameTime
         {
             get;
             private set;
         }
        static internal GraphicsDeviceManager manager;
        public static GraphicsDeviceManager GraphicsDeviceManager
        {
            get { return manager; }
        }

        internal static SpriteBatch batch;
        public static SpriteBatch SpriteBatch
        {
            get { return batch; }
        }

        internal static ContentManager content;
        public static ContentManager ContentManager
        {
            get { return content; }
        }

        /// <summary>
        /// Initializes the specified g.
        /// </summary>
        /// <param name="g">The game.</param>
        /// <param name="graphics">The graphics device manager.</param>
        /// <param name="excludedModules">List of modules to disable by default.</param>
        public static void Initialize(Game g, GraphicsDeviceManager manag, List<string> excludedModules)
        {
            LastId = 0;
            manager = manag;
            batch = new SpriteBatch(manager.GraphicsDevice);
            content = g.Content;


            #region Module Loading
            Modules.mods = new Dictionary<string, Module>();
            
            //Add default modules.
            Modules.AddModule("Engine.Logging", new LoggingModule());
            Modules.AddModule("Engine.Settings", new SettingsModule());
            Modules.Logging.Write(Modules.Settings.EngineName + " Initializing",LogLevel.Debug);
            Modules.Logging.Write("Initializing EmbeddedContentManager", LogLevel.Debug);
            Modules.AddModule("Engine.EmbeddedContentManager", new EmbeddedContentManagerModule());
            Modules.Logging.Write("Initializing DebugManager", LogLevel.Debug);
            Modules.AddModule("Engine.Debug", new DebugModule());

            //These may not be disabled.
            Modules.Logging.Write("Initializing GraphicsManager", LogLevel.Debug);
            Modules.AddModule("Engine.GraphicsManager", new GraphicsManagerModule());
            Modules.Logging.Write("Initializing SceneManager", LogLevel.Debug);
            Modules.AddModule("Engine.SceneManager", new SceneManagerModule());
            Modules.Logging.Write("Initializing ContentManager", LogLevel.Debug);
            Modules.AddModule("Engine.ContentManager", new ContentManagerModule());
            Modules.Logging.Write("Initializing TextureManager", LogLevel.Debug);
            Modules.AddModule("Engine.TextureManager", new TextureManagerModule());
            Modules.Logging.Write("Initializing FontManager", LogLevel.Debug);
            Modules.AddModule("Engine.FontManager", new FontManagerModule());
            ////////////////////////
            Modules.Logging.Write("Initializing PhysicsManager", LogLevel.Debug);
            Modules.AddModule("Engine.PhysicsManager", new PhysicsManagerModule());
            Modules.Logging.Write("Initializing SoundManager", LogLevel.Debug);
            Modules.AddModule("Engine.SoundManager", new SoundManagerModule());


            //Input modules.
#if WINDOWS
            Modules.Logging.Write("Initializing Keyboard and Mouse Input", LogLevel.Debug);
            Modules.AddModule("Engine.KeyboardInput", new KeyboardInputModule());
            Modules.AddModule("Engine.MouseInput", new MouseInputModule());
#endif
#if ZUNE
            Modules.Logging.Write("Initializing Touchscreen and Accelerometer Input",LogLevel.Debug);
            Modules.AddModule("Engine.TouchscreenInput", new TouchscreenInputModule());
            Modules.AddModule("Engine.AccelerometerInput", new AccelerometerInputModule()); 
#endif
#if XBOX
            Modules.Logging.Write("Initializing GamePad Input",LogLevel.Debug);
            Modules.AddModule("Engine.GamepadInput",new GamepadInputModule());
#endif
            if (excludedModules.Count != 0)
                Modules.Logging.Write("Disabling modules.",LogLevel.Debug);

            foreach (string mod in excludedModules)
            {
                Modules.DisableModule(mod);
            }

            #endregion

        }

        public static void Initialize(Game g, GraphicsDeviceManager graphics)
        {
            Initialize(g, graphics, new List<string>());
        }

        public static void Draw()
        {
            SpriteBatch.Begin();
            Modules.Draw();
            SpriteBatch.End();
        }

        public static void Update(GameTime gameTime)
        {
            GameTime = gameTime;
            Modules.Update();
        }
    }
}
